package vg.modules.search.components.searchTreePanel.components;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Set;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import vg.modules.search.SearchPluginGlobals;
import vg.modules.search.components.FBSecondPanel;
import vg.services.data_base_manager.data.graph.Graph;
import vg.services.data_base_manager.data.skeleton.GraphTreeElement;
import vg.services.graph_view_manager.interfaces.graph_view.AGraphView;
import vg.services.graph_view_manager.interfaces.graph_view.IGraphRenderer;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.actions.ShowAttributesAction;
import vg.services.main_manager.MainManager;
import vg.services.plugin_manager.event_and_request.request.UIRequestAddTab;
import vg.services.plugin_manager.event_and_request.request.UIRequestReplaceCurrentTab;
import vg.services.plugin_manager.realization.PluginParameter;

/**
 * This class realizes menu item for opening of composition
 * of vertices in new tab.
 *
 * @author Timur Zolotuhin (e-mail: tzolotuhin@gmail.com)
 */
public class OpenVerticesMenuItem implements IMenuItem {
	private final JMenuItem jItem;
	private final OpenVerticesAction action;

	public OpenVerticesMenuItem(final JTree tree, final FBSecondPanel fbSecondPanel, final PluginParameter parameter) {
		this.action = new OpenVerticesAction(tree, fbSecondPanel, parameter);
		this.jItem = new JMenuItem("Open vertices");
		final Icon icon = new ImageIcon("data/resources/textures/vertexBall.png");
		this.jItem.setIcon(icon);
		this.jItem.addActionListener(this.action);
	}

    @Override
    public JMenuItem getMenuItem() {
		return(this.jItem);
	}

    @Override
    public boolean isVisible() {
		return(this.action.isVisible());
	}

    @Override
    public void updateTheme() {
		SwingUtilities.updateComponentTreeUI(this.jItem);
	}
}
/**
 * Opens composition of vertices in new tab.
 *
 * @author Timur Zolotuhin (e-mail: tzolotuhin@gmail.com)
 */
class OpenVerticesAction implements ActionListener {
	private final JTree tree;
	private final PluginParameter parameter;
	private FBSecondPanel fbSecondPanel;

	public OpenVerticesAction(final JTree tree, final FBSecondPanel fbSecondPanel, final PluginParameter parameter) {
		this.tree = tree;
		this.parameter = parameter;
		this.fbSecondPanel = fbSecondPanel;
	}

	@Override
    public void actionPerformed(ActionEvent e) {
		MainManager.logger.printDebug("[" + this.getClass().getName()+".actionPerformed] [PROCESS] Opening of composition of vertexes in new tab (from navigator).");

        if (!isVisible()) {
            MainManager.logger.printDebug("[" + this.getClass().getName()+".actionPerformed] [BAD] Opening of composition of vertexes in new tab(from navigator).");
            return;
        }

        TreePath[] treePaths = tree.getSelectionPaths();
        TreeModel treeModel = tree.getModel();
        if (treeModel == null || treePaths == null) {
            MainManager.logger.printDebug("[" + this.getClass().getName()+".actionPerformed] [BAD] Opening of composition of vertexes in new tab(from navigator). Model = null.");
            return;
        }

        ArrayList<Integer>vertexes = new ArrayList<Integer>();
        for (TreePath treePath : treePaths) {
            GraphTreeElement node = ((GraphTreeElement)treeModel.getRoot()).vg_getNode(treePath);
            if((node.vg_getType() & GraphTreeElement.DEF_VERTEX_TYPE) > 0) {
                int db_id = node.vg_getVertexId();
                vertexes.add(db_id);
            } else {
                MainManager.logger.printDebug("[" + this.getClass().getName()+".actionPerformed] [BAD] Opening of composition of vertexes in new tab(from navigator). Type of node is not DEF_VERTEX.");
                MainManager.windowMessage.warningMessage("Warning: Elements aren't vertex of graph(May be it is tab or tabs).", "Opening of vertexes");
                return;
            }
        }
        Graph ssg = this.parameter.graphDataBase.getSubGraph(vertexes);
        Set<String>attrs = this.fbSecondPanel.getVertexAdditionalAttributes();

        final AGraphView igv = MainManager.graphViewManager.newGraphView(ssg);
        igv.addAction(new ShowAttributesAction(attrs, attrs) {
            @Override
            public void finishAction(IGraphRenderer graphRenderer) {
                if(fbSecondPanel.getActionMode() == SearchPluginGlobals.DEF_ACTION_MODE_1) {
                    UIRequestAddTab req = new UIRequestAddTab(igv);
                    parameter.userInterfaceManager.sendRequest(req);
                } else {
                    UIRequestReplaceCurrentTab req = new UIRequestReplaceCurrentTab(igv, null);
                    parameter.userInterfaceManager.sendRequest(req);
                }
            }
        });
    }

    public boolean isVisible() {
		if(this.tree != null) {
			TreePath[] treePaths = this.tree.getSelectionPaths();
			if(treePaths != null) {
				if(treePaths.length == 1) {
					TreeModel tm = this.tree.getModel();
					if(tm != null) {
						GraphTreeElement node = ((GraphTreeElement)tm.getRoot()).vg_getNode(treePaths[0]);
						if(node != null && (node.vg_getType() & GraphTreeElement.DEF_VERTEX_TYPE) > 0) {
							return(true);
						}
					}
				} else if(treePaths.length > 0) {
					TreePath path = treePaths[0].getParentPath();
					if(path != null) {
						TreeModel tm = tree.getModel();
						if(tm != null) {
							String s = path.toString();
							boolean check = false; // check all selected nodes, that they have one parent
							for(TreePath treePath : treePaths) {
								GraphTreeElement node = ((GraphTreeElement)tm.getRoot()).vg_getNode(treePath);
								if(!s.equals(treePath.getParentPath().toString()) || node == null || (node.vg_getType() & GraphTreeElement.DEF_VERTEX_TYPE) == 0) {
									check = true;
									break;
								}
							}
							return(!check);
						}
					} 
				}
			}
		}
		return(false);
	}
}
